﻿using IM.Easy.Core.Services;
using IM.Easy.Core.Utils;
using IM.Easy.Entity.System;
using IM.Easy.SystemServices.Dtos;
using IM.Easy.SystemServices.IServices;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IM.Easy.SystemServices.Services
{
    /// <summary>
    /// 菜单服务
    /// </summary>
    public class MenuService(ISqlSugarClient db) : AppServices<SysMenu>(db), IMenuService
    {
        /// <summary>
        /// 获取用户菜单->普通用户
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<SysMenu> GetMenuTreeByUserId(long userId)
        {

            // 构建用户权限菜单查询
            var userMenusQuery = Db.Queryable<SysUser, SysUserRole, SysRoleMenu, SysMenu, SysRole>(
                (u, ur, rm, m, r) => new JoinQueryInfos(
                    JoinType.Inner, u.Id == ur.UserId,
                    JoinType.Inner, ur.RoleId == rm.RoleId,
                    JoinType.Inner, rm.MenuId == m.Id,
                    JoinType.Inner, r.Id == rm.RoleId
                ))
                .Where(u => u.Id == userId)
                .Where((u, ur, rm, m, r) => m.IsActive && r.IsActive)
                .Select((u, ur, rm, m) => m);

            // 构建开放菜单查询
            var openMenusQuery = Db.Queryable<SysMenu>()
                .Where(m => !m.RequiresAuth && m.IsActive && (m.MenuType == MenuType.Directory || m.MenuType == MenuType.Menu))
                .Select(m => m);

            // 合并查询并在数据库层面去重和排序
            var combinedMenus = Db.UnionAll(userMenusQuery, openMenusQuery)
                .Distinct()
                .OrderBy(m => m.Order)
                .ToTree(s => s.Children, s => s.ParentId, 0);

            return combinedMenus;

        }

        /// <summary>
        /// 获取所有的菜单树-> 超级管理员
        /// </summary>
        /// <returns></returns>
        public List<SysMenu> GetMenuTree()
        {
            var menus = Db.Queryable<SysMenu>()
                .Where(s => s.IsActive)
                .OrderBy(s => s.Order)
                .ToTree(s => s.Children, s => s.ParentId, 0);
            return menus;
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>

        public List<SysMenu> GetMenuList(MenuQueryDto queryDto)
        {
            var queryable = Context.Queryable<SysMenu>();
            var exp = Expressionable.Create<SysMenu>();
            exp = exp.AndIF(queryDto.MenuType != default, s => queryDto.MenuType.Contains(s.MenuType))
                    .AndIF(queryDto.Pid != default, s => s.ParentId == queryDto.Pid.Value);
            var list = db.Queryable<SysMenu>()
                         .Where(exp.ToExpression())
                         .OrderBy(s => s.Order)
                         .ToList();
            return list;
        }

        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public SysMenu GetMenu(long id)
        {
            return db.Queryable<SysMenu>().InSingle(id);
        }

        /// <summary>
        /// 获取菜单
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public SysMenu GetMenu(MenuInfoQueryDto parm)
        {
            var menu = Context.Queryable<SysMenu>()
                .IF(parm.LeafNode, s => s.Includes(s => s.Children))
                .InSingle(parm.Id);

            return menu;
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <param name="menu"></param>
        /// <returns>返回当前菜单ID</returns>
        public long AddMenu(SysMenu menu)
        {
            var id = db.Insertable(menu).ExecuteReturnSnowflakeId();
            return id;
        }

        /// <summary>
        /// 更新菜单
        /// </summary>
        /// <param name="menu"></param>
        /// <returns>返回当前菜单ID</returns>
        public bool UpdateMenu(SysMenu menu)
        {
            return db.Updateable(menu).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteMenu(long id)
        {
            if (HasChildren(id))
            {
                ExceptionUtils.ThrowBusinessException("存在子菜单，禁止删除");
            }
            if (HasBindRole(id))
            {
                ExceptionUtils.ThrowBusinessException("菜单已分配，禁止删除");
            }

            return Db.Deleteable<SysMenu>(id).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 判断是否存在子节点
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool HasChildren(long id)
        {
            return Db.Queryable<SysMenu>().Any(s => s.ParentId == id);
        }

        /// <summary>
        /// 是否已绑定角色
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool HasBindRole(long id)
        {
            return Db.Queryable<SysRoleMenu>().Any(s => s.MenuId == id);
        }


    }
}
